package admindao

import (
	"go.uber.org/zap"
	"strings"
	"wzgames/internal/admin/api/wzabind"
	"wzgames/internal/admin/model"
	"wzgames/internal/gdao"
	"wzgames/internal/model/user"
	"wzgames/internal/response"
	"wzgames/pkg/logger"
)

type WalletDao gdao.DaoSource

const sqlGetBetPendingCount = "select count(*) from wallet_bet_pending"

func (dao *WalletDao) GetBetPendingCount(req wzabind.BetPendingSsReq) (int, error) {
	var c int
	var sb strings.Builder
	sb.WriteString(sqlGetBetPendingCount)
	s1, args := dao.genBetPendingWhere(req)
	sb.WriteString(s1)
	err := dao.Get(&c, sb.String(), args...)
	return c, err
}

func (dao *WalletDao) genBetPendingWhere(req wzabind.BetPendingSsReq) (string, []interface{}) {
	var sb strings.Builder
	var items []string
	var args []interface{}
	sb.WriteString(" where `stm`=0 ")
	if req.Tp > 0 {
		if req.Tp == 0 {
			items = append(items, " `gact` in(1,3,4,5,6) ")
		} else if req.Tp == 1 {
			items = append(items, " `gact` in(3,4,6) ")
		} else if req.Tp == 2 {
			items = append(items, " `gact`=5 ")
		} else if req.Tp == 3 {
			if req.GameId > 0 && req.GameId != 100 {
				items = append(items, " `gact`=1 and `gameid`=? ")
				args = append(args, req.GameId)
			} else {
				items = append(items, " `gact`=1 and `gameid`>100  and `gameid`<109 ")
			}
		} else if req.Tp == 4 {
			items = append(items, " `gact`=1 and `gameid`=100 ")
		} else if req.Tp == 5 {
			items = append(items, " `gact`=1 and `gameid`=109 ")
		}
	}
	if req.NodeId > 0 {
		items = append(items, " `nodeid`=?")
		args = append(args, req.NodeId)
	}
	if req.Uid > 0 {
		items = append(items, " `uid`=?")
		args = append(args, req.Uid)
	}
	if req.InstId > 0 {
		items = append(items, " `inst`=?")
		args = append(args, req.InstId)
	}
	if req.RoundId > 0 {
		items = append(items, " `roundid`=?")
		args = append(args, req.RoundId)
	}
	if req.GameId > 0 && req.Tp < 3 {
		items = append(items, " `gameid`=?")
		args = append(args, req.GameId)
	}

	if len(items) > 0 {
		sb.WriteString(" and ")
		sb.WriteString(strings.Join(items, " and "))
	}
	return sb.String(), args
}

const sqlGetBetPendingByCond = "select * from wallet_bet_pending"

func (dao *WalletDao) GetBetPendingByCond(req wzabind.BetPendingSsReq, offset int) ([]*user.WalletBetPending, error) {
	var sb strings.Builder
	sb.WriteString(sqlGetBetPendingByCond)
	s1, args := dao.genBetPendingWhere(req)
	sb.WriteString(s1)
	if req.PageSize <= 0 {
		sb.WriteString(" order by bettime asc")
	} else if offset <= 0 {
		sb.WriteString(" order by bettime asc limit ?")
		args = append(args, req.PageSize)
	} else {
		sb.WriteString(" order by bettime asc limit ?,?")
		args = append(args, offset, req.PageSize)
	}
	rows, err := dao.Queryx(sb.String(), args...)
	if err != nil {
		//logger.Error("err == ", zap.String("error", err.Error()))
		return nil, err
	}
	var ret []*user.WalletBetPending
	for rows.Next() {
		rd := &user.WalletBetPending{}
		err = rows.StructScan(rd)
		if err != nil {
			//logger.Error("err == ", zap.String("error", err.Error()))
			return nil, err
		}
		ret = append(ret, rd)
	}
	return ret, err
}

const sqlGetGameBetPending = "select count(*) as num,`roundid`,`inst`,`nodeid` from wallet_bet_pending where `gact`=1 and `gameid`=? and `stm`=0 GROUP BY `inst`,`nodeid`,`roundid` order by `roundid` asc limit ?"

func (dao *WalletDao) GetGameBetPending(gameId int32, limit int64) ([]*model.BetPendingGroup, error) {
	rows, err := dao.Queryx(sqlGetGameBetPending, gameId, limit)
	if err != nil {
		//logger.Error("err == ", zap.String("error", err.Error()))
		return nil, err
	}
	var ret []*model.BetPendingGroup
	for rows.Next() {
		rd := &model.BetPendingGroup{}
		err = rows.StructScan(rd)
		if err != nil {
			//logger.Error("err == ", zap.String("error", err.Error()))
			return nil, err
		}
		ret = append(ret, rd)
	}
	return ret, err
}

const sqlGetBetPendingIn = "select * from wallet_bet_pending where `betid` in("

func (dao *WalletDao) GetBetPendingIn(ids string) (map[uint64]*user.WalletBetPending, int, error) {
	var sqlTmp = sqlGetBetPendingIn + ids + ")"
	rows, err := dao.Queryx(sqlTmp)
	if err != nil {
		//logger.Error("err == ", zap.String("error", err.Error()))
		return nil, 0, err
	}
	ret := make(map[uint64]*user.WalletBetPending)
	c := 0
	for rows.Next() {
		rd := &user.WalletBetPending{}
		err = rows.StructScan(rd)
		if err != nil {
			logger.Error("err == ", zap.String("error", err.Error()))
			return nil, 0, err
		}
		ret[rd.BetId] = rd
		c++
	}
	return ret, c, err
}

const sqlGetUserWallets = "select `uid`,`agtid`,`wv`,`curr`,`created`,`updated`,`balance` from wallet where `uid`=? order by updated desc"

func (dao *WalletDao) GetUserWallets(uid uint64) ([]*user.WalletEntity, error) {
	rows, err := dao.Queryx(sqlGetUserWallets, uid)
	if err != nil {
		logger.Error("err == ", zap.String("error", err.Error()))
		return nil, err
	}
	var ret []*user.WalletEntity
	for rows.Next() {
		rd := &user.WalletEntity{}
		err = rows.StructScan(rd)
		if err != nil {
			logger.Error("err == ", zap.String("error", err.Error()))
			return nil, err
		}
		rd.Balance = response.TrimAmtZeros(rd.Balance)
		ret = append(ret, rd)
	}
	return ret, err
}

const sqlGetUserWalletTransfers = "select `tid`,`uid`,`agtid`,`agtuid`,`uname`,`ucurrency`,`actype`,`status`,`created`,`updated`,`amount`,`balance`,`obalance`,`fromid` from wallet_transfer"

func (dao *WalletDao) GetUserWalletTransfers(offset int, req wzabind.WzWalletTransferReq) ([]*model.WalletTransfer, error) {
	var sb strings.Builder
	sb.WriteString(sqlGetUserWalletTransfers)
	var items []string
	var args []interface{}
	if req.Uid > 0 {
		items = append(items, " `uid`=?")
		args = append(args, req.Uid)
	}
	if req.Tid > 0 {
		items = append(items, " `tid`=?")
		args = append(args, req.Tid)
	}
	if req.AcType > -1 {
		items = append(items, " `actype`=?")
		args = append(args, req.AcType)
	}
	if req.Curr != "" {
		items = append(items, " `ucurrency`=?")
		args = append(args, req.Curr)
	}
	if req.OrderId != "" {
		items = append(items, " `fromid`=?")
		args = append(args, req.OrderId)
	}
	if len(items) > 0 {
		sb.WriteString(" where ")
		sb.WriteString(strings.Join(items, " and "))
	}
	if req.PageSize <= 0 {
		sb.WriteString(" order by updated desc")
	} else if offset <= 0 {
		sb.WriteString(" order by updated desc limit ?")
		args = append(args, req.PageSize)
	} else {
		sb.WriteString(" order by updated desc limit ?,?")
		args = append(args, offset, req.PageSize)
	}
	rows, err := dao.Queryx(sb.String(), args...)
	if err != nil {
		logger.Error("err == ", zap.String("error", err.Error()))
		return nil, err
	}
	var ret []*model.WalletTransfer
	for rows.Next() {
		rd := &model.WalletTransfer{}
		err = rows.StructScan(rd)
		if err != nil {
			logger.Error("err == ", zap.String("error", err.Error()))
			return nil, err
		}
		rd.Amount = response.TrimAmtZeros(rd.Amount)
		rd.Balance = response.TrimAmtZeros(rd.Balance)
		rd.OBalance = response.TrimAmtZeros(rd.OBalance)
		ret = append(ret, rd)
	}
	return ret, err
}
